//
//  TargetType.swift
//  MSAPI
//
//  Created by mrsong on 2020/4/15.
//

import Foundation

public enum HTTPMethod: String {
    case get
    case post
}

/// 请求行. 路径、方法、参数
public struct RequestLine {
    public let path: String?
    public let parameters: [String: Any]?
    public let method: HTTPMethod
    
    public init(path: String?, parameters: [String: Any]?, method: HTTPMethod) {
        self.path = path
        self.parameters = parameters
        self.method = method
    }
}

public protocol TargetType {
    /// 基础 URL
    var baseURL: URL { get }
    
    /// 请求行
    var requestLine: RequestLine { get }
    
    /// HTTP 头部字段
    var headers: [String: String]? { get }
    
//    /// 超时时间
//    var timeoutInterval: Double? { get }
//
//    /// 示例
//    var sampleData: [String: Any] { get }
}

extension TargetType {
    func urlRequest() -> URLRequest {
        let url: URL
        // 添加 path
        if let path = requestLine.path {
            url = baseURL.appendingPathComponent(path)
        } else {
            url = baseURL
        }
        var request = URLRequest(url:url)
        request.httpMethod = requestLine.method.rawValue
        request.allHTTPHeaderFields = headers
        if let parameters = requestLine.parameters {
            switch requestLine.method {
            case .get:
                // get 请求，把 parameters 拼接到 URL 上
                request.url = url.addParameters(parameters)
            case .post:
                // post 请求，把 parameters 设置到 httpBody 中
                request.httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: JSONSerialization.WritingOptions.prettyPrinted)
            }
        }
        return request
    }
}

extension URL {
    func addParameters(_ parameters: [String: Any]) -> URL? {
        guard !parameters.isEmpty else { return self }
        guard var urlComponents = URLComponents(url: self, resolvingAgainstBaseURL: false) else { return nil }
        var queryItems = urlComponents.queryItems ?? []
        queryItems.append(contentsOf: parameters.map({ URLQueryItem(name: $0.key, value: "\($0.value)")}))
        urlComponents.queryItems = queryItems
        return urlComponents.url
    }
}
